// MegaButton.cpp : implementation file
//

#include "stdafx.h"
#include "MegaButton.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMegaButton

CMegaButton::CMegaButton()
{
	m_pOutBmp = m_pDownBmp = m_pOverBmp = 
	m_pCheckOutBmp = m_pCheckDownBmp = m_pCheckOverBmp = 
	m_pDisabledBmp = NULL;

	m_bMouseOver = false;
	m_bLButtonDown = false;
	m_nType = MBT_PUSH;
	m_nCheckState = MBS_UNCHECK;

	m_pOldBackBmp = NULL;
}

CMegaButton::~CMegaButton()
{
	if(m_pOutBmp)		delete m_pOutBmp;
	if(m_pDownBmp)		delete m_pDownBmp;
	if(m_pOverBmp)		delete m_pOverBmp;
	if(m_pCheckOutBmp)	delete m_pCheckOutBmp;
	if(m_pCheckDownBmp) delete m_pCheckDownBmp;
	if(m_pCheckOverBmp) delete m_pCheckOverBmp;
	if(m_pDisabledBmp)	delete m_pDisabledBmp;
}

void CMegaButton::SetCheck(MBCheckState nState)
{
	m_nCheckState = nState;
	RedrawWindow();
}

MBCheckState CMegaButton::GetCheck()
{
	return m_nCheckState;
}

void CMegaButton::GetSize(LPRECT prect)
{
	CSize sz = m_pOutBmp->GetBitmapDimension();
	prect->left = 0;
	prect->top = 0;
	prect->right = sz.cx;
	prect->bottom = sz.cy;
}

void CMegaButton::SetBitmaps(UINT uiOut, UINT uiDown, UINT uiOver, UINT uiDisabled /*=NULL*/)
{
	if(m_pOutBmp)		delete m_pOutBmp;
	if(m_pDownBmp)		delete m_pDownBmp;
	if(m_pOverBmp)		delete m_pOverBmp;

	m_pOutBmp		= new CMegaBitmap();
	m_pDownBmp		= new CMegaBitmap();
	m_pOverBmp		= new CMegaBitmap();

	if(!m_pOutBmp->LoadBitmap(uiOut)) MessageBox("error");
	if(!m_pDownBmp->LoadBitmap(uiDown)) MessageBox("error");
	if(!m_pOverBmp->LoadBitmap(uiOver)) MessageBox("error");

	if(uiDisabled)
	{
		if(m_pCheckOutBmp)	delete m_pCheckOutBmp;
		if(m_pCheckDownBmp) delete m_pCheckDownBmp;
		if(m_pCheckOverBmp) delete m_pCheckOverBmp;
		if(m_pDisabledBmp)	delete m_pDisabledBmp;

		m_pCheckOutBmp	= new CMegaBitmap();
		m_pCheckDownBmp	= new CMegaBitmap();
		m_pCheckOverBmp = new CMegaBitmap();
		m_pDisabledBmp	= new CMegaBitmap();

		if(!m_pCheckOutBmp->LoadBitmap(uiDown)) MessageBox("error");
		if(!m_pCheckDownBmp->LoadBitmap(uiDown)) MessageBox("error");
		if(!m_pCheckOverBmp->LoadBitmap(uiDown)) MessageBox("error");
		if(!m_pDisabledBmp->LoadBitmap(uiDisabled)) MessageBox("error");
	}

	CSize sz = m_pOutBmp->GetBitmapDimension();
	SetWindowPos(NULL, 0, 0, sz.cx, sz.cy, SWP_NOZORDER|SWP_NOMOVE);
}

void CMegaButton::SetBitmaps(UINT uiCheckOut, UINT uiCheckDown, UINT uiCheckOver, 
				UINT uiOut, UINT uiDown, UINT uiOver, UINT uiDisabled /*=NULL*/)
{
	if(m_pOutBmp)		delete m_pOutBmp;
	if(m_pDownBmp)		delete m_pDownBmp;
	if(m_pOverBmp)		delete m_pOverBmp;
	if(m_pCheckOutBmp)	delete m_pCheckOutBmp;
	if(m_pCheckDownBmp) delete m_pCheckDownBmp;
	if(m_pCheckOverBmp) delete m_pCheckOverBmp;

	m_pOutBmp		= new CMegaBitmap();
	m_pDownBmp		= new CMegaBitmap();
	m_pOverBmp		= new CMegaBitmap();
	m_pCheckOutBmp	= new CMegaBitmap();
	m_pCheckDownBmp	= new CMegaBitmap();
	m_pCheckOverBmp = new CMegaBitmap();

	if(!m_pOutBmp->LoadBitmap(uiOut)) MessageBox("error");
	if(!m_pDownBmp->LoadBitmap(uiDown)) MessageBox("error");
	if(!m_pOverBmp->LoadBitmap(uiOver)) MessageBox("error");
	if(!m_pCheckOutBmp->LoadBitmap(uiCheckOut)) MessageBox("error");
	if(!m_pCheckDownBmp->LoadBitmap(uiCheckDown)) MessageBox("error");
	if(!m_pCheckOverBmp->LoadBitmap(uiCheckOver)) MessageBox("error");

	if(uiDisabled)
	{
		if(m_pDisabledBmp)	delete m_pDisabledBmp;
		m_pDisabledBmp	= new CMegaBitmap();
		if(!m_pDisabledBmp->LoadBitmap(uiDisabled)) MessageBox("error");
	}

	CSize sz = m_pOutBmp->GetBitmapDimension();
	SetWindowPos(NULL, 0, 0, sz.cx, sz.cy, SWP_NOZORDER|SWP_NOMOVE);
}

void CMegaButton::SetBackgroundBmp(CMegaBitmap * pBack)
{
	// copy parent's background into internal DC
	// do it only once
	CWnd * pParent = GetParent();
	CClientDC ParentDC(pParent);
	CDC TmpDC;
	TmpDC.CreateCompatibleDC(&ParentDC);
	CGdiObject * pOldBmp = TmpDC.SelectObject(pBack);

	m_dcBack.CreateCompatibleDC(&ParentDC);

	CRect rcw;
	GetWindowRect(&rcw);
	GetParent()->ScreenToClient(&rcw);
	m_BackBmp.CreateCompatibleBitmap(&ParentDC, rcw.Width(), rcw.Height());
	m_pOldBackBmp = m_dcBack.SelectObject(&m_BackBmp);
	m_dcBack.BitBlt(0, 0, rcw.Width(), rcw.Height(), &TmpDC, rcw.left, rcw.top, SRCCOPY);

	TmpDC.SelectObject(pOldBmp);
}

BEGIN_MESSAGE_MAP(CMegaButton, CButton)
	//{{AFX_MSG_MAP(CMegaButton)
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_CAPTURECHANGED()
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMegaButton message handlers

void CMegaButton::OnPaint() 
{
	CPaintDC dc(this); // device context for painting

	CMegaBitmap * pCurBmp = NULL;

	if(m_pDisabledBmp && !IsWindowEnabled())
		pCurBmp = m_pDisabledBmp;
	else
	{
		MBCheckState nCheck = GetCheck();
		switch(m_nType)
		{
		case MBT_PUSH:
			if(nCheck == MBS_CHECK)
				pCurBmp = m_pDownBmp;
			else
				if(m_bMouseOver)
					pCurBmp = m_pOverBmp;
				else
					pCurBmp = m_pOutBmp;
			break;
		case MBT_CHECK:
		case MBT_RADIO:
			if(nCheck == MBS_CHECK)
				if(m_bMouseOver)
					if(m_bLButtonDown)
						pCurBmp = m_pCheckDownBmp;
					else
						pCurBmp = m_pCheckOverBmp;
				else
					pCurBmp = m_pCheckOutBmp;
			else
				if(m_bMouseOver)
					if(m_bLButtonDown)
						pCurBmp = m_pDownBmp;
					else
						pCurBmp = m_pOverBmp;
				else
					pCurBmp = m_pOutBmp;
			break;
		}
	}
	
	// TODO: Add your message handler code here
	if(pCurBmp)
	{
		CSize sz = pCurBmp->GetBitmapDimension();

		CDC MemDC;
		MemDC.CreateCompatibleDC(&dc);
		CBitmap Bmp;
		Bmp.CreateCompatibleBitmap(&dc, sz.cx, sz.cy);
		CGdiObject * pOldBmp = MemDC.SelectObject(&Bmp);

		// copy parent's background first
		MemDC.BitBlt(0, 0, sz.cx, sz.cy, &m_dcBack, 0, 0, SRCCOPY);
		pCurBmp->DrawTransparent(&MemDC, 0, 0, RGB(255, 0, 0));

		dc.BitBlt(0, 0, sz.cx, sz.cy, &MemDC, 0, 0, SRCCOPY);

		MemDC.SelectObject(pOldBmp);
	}
}

void CMegaButton::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CRect rc;
	GetClientRect(&rc);
	if(!rc.PtInRect(point))
		return ;

	m_bLButtonDown = true;
	if(m_nType == MBT_PUSH)
	{
		m_nCheckState = MBS_CHECK;
		RedrawWindow();
	}
	else
	if(m_nType == MBT_CHECK)
	{
		m_nCheckState = (m_nCheckState == MBS_CHECK ? MBS_UNCHECK : MBS_CHECK);
		RedrawWindow();
		GetParent()->SendMessage(WM_COMMAND, MAKELONG(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
	}
	else
	if(m_nType == MBT_RADIO && m_nCheckState == MBS_UNCHECK)
	{
		m_nCheckState = MBS_CHECK;
		RedrawWindow();
		GetParent()->SendMessage(WM_COMMAND, MAKELONG(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
	}
}

void CMegaButton::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	m_bLButtonDown = false;
	CRect rc;
	GetClientRect(&rc);
	if(!rc.PtInRect(point))
		return ;

	if(m_nType == MBT_PUSH)
	{
		m_nCheckState = MBS_UNCHECK;
		RedrawWindow();
		GetParent()->SendMessage(WM_COMMAND, MAKELONG(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
	}
	else
	{
		RedrawWindow();
	}
}

void CMegaButton::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CRect rc;
	GetClientRect(&rc);
	if(rc.PtInRect(point))
	{
		if(!m_bMouseOver)
		{
			m_bMouseOver = true;
			SetCapture();
		}
	}
	else
	{
		m_bMouseOver = false;
		m_bLButtonDown = false;
		if(m_nType == MBT_PUSH)
			m_nCheckState = MBS_UNCHECK;
		ReleaseCapture();
	}
	RedrawWindow();
}


void CMegaButton::OnCaptureChanged(CWnd *pWnd) 
{
	// TODO: Add your message handler code here
	m_bMouseOver = false;
	ReleaseCapture();
	RedrawWindow();

	CButton::OnCaptureChanged(pWnd);
}

int CMegaButton::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CButton::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	if(lpCreateStruct->style & BS_PUSHBUTTON)
		m_nType = MBT_PUSH;
	else
	if(lpCreateStruct->style & BS_AUTOCHECKBOX)
		m_nType = MBT_CHECK;
	else
	if(lpCreateStruct->style & BS_RADIOBUTTON)
		m_nType = MBT_RADIO;

	return 0;
}
